package com.evil.formula.util;

import com.evil.formula.enums.FormulaErrCodeEnum;
import com.evil.formula.enums.FunctionEnum;
import com.evil.formula.exception.FormulaException;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author liyang
 * @date 2023-10-30 17:47
 */
public class FormulaUtil {

    /**
     * 检查值的类型，并抛出错误
     *
     * @param tClass   值应该的类型，如“number”，“boolean”， “string”，必须字符床
     * @param funcName 函数名称，用于类型检查报错
     * @param startIdx 参数开始开始的位置，从0开始
     * @param values   要检查类型的值
     */
    public static void checkValueType(Class<?> tClass, FunctionEnum funcName, int startIdx, Object... values) {
        if (null == values || values.length == 0) {
            return;
        }
        for (int i = 0, valuesLength = values.length; i < valuesLength; i++) {
            Object value = values[i];
            if (null == value || !value.getClass().equals(tClass)) {
                throw new FormulaException(FormulaErrCodeEnum.PARAM_TYPE_ERROR, funcName.name(), startIdx + i + 1);
            }
        }
    }

    /**
     * 检查参数的个数是否正确
     *
     * @param funcName 函数名称，用于类型检查报错
     * @param count    期待参数个数
     * @param values   参数列表
     */
    public static void checkParamCount(String funcName, int count, Object... values) {
        // 校验长度为0
        if (count == 0 && null != values && values.length != 0) {
            throw new FormulaException(FormulaErrCodeEnum.PARAM_COUNT_ERROR, funcName, count, values.length);
        }
        // 校验长度不为0
        if (count != 0 && (null == values || values.length == 0)) {
            throw new FormulaException(FormulaErrCodeEnum.PARAM_COUNT_ERROR, funcName, count, null == values ? 0 : values.length);
        }
    }

    /**
     * 字符串反转
     *
     * @param value value
     * @return String
     */
    public static String reverse(String value) {
        return StringUtils.reverse(value);
    }

    /**
     * 去除数组中为null的值
     *
     * @param values 需要剔除无用数值的数组
     * @param <T>    值
     * @return 列表
     */
    public static <T> List<T> removeNullParam(T... values) {
        return Arrays.stream(values).filter(Objects::nonNull).collect(Collectors.toList());
    }

    /**
     * 去除数组中为null的值
     *
     * @param values 需要剔除无用数值的数组
     * @return 列表
     */
    public static List<Object> replaceNullParam(List<Object> values) {
        List<Object> replacedValues = new ArrayList<>();
        for (Object value : values) {
            replacedValues.add(Objects.requireNonNullElse(value, 0));
        }
        return replacedValues;
    }

    /**
     * 获取字符串中第一个数字，小数也可以获取
     *
     * @param value value
     * @return BigDecimal
     */
    public static BigDecimal getFirstNum(String value) {
        if (StringUtils.isBlank(value)) {
            return null;
        }
        Matcher matcher = Pattern.compile("/(-)*[0-9]\\d*(\\.\\d+)?/g").matcher(value);
        if (matcher.find()) {
            return new BigDecimal(matcher.group());
        }
        return null;
    }
}
